<?php

    /**
     * Object
     *
     * @package      Core
     *
     * @license      Open Software License (OSL 3.0) see LICENCE-OSL file or http://opensource.org/licenses/osl-3.0.php
     */
    class Core_Object
    {

    ////////////////////////////////////////////////////////////////////////////
    //                                Variables                               //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Object attributes
         *
         * @var array
         */
        protected $_data = array();

    ////////////////////////////////////////////////////////////////////////////
    //                                 Methods                                //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Constructor
         */
        public function __construct()
        {
            $args = func_get_args();

            if (empty($args[0])) {
                $args[0] = array();
            }

            $this->_data = $args[0];
        }

		/**
		 * Destructor
		 */
		public function __destruct()
		{
			unset($this);
		}

        /**
         * Converts object attributes to array
         *
         * @param       array       $arrAttributes : array of required attributes
         * @return      array
         */
        public function toArray(array $arrAttributes = array())
        {
            if (empty($arrAttributes)) {
                return $this->_data;
            }

            $arrRes = array();
            foreach ($arrAttributes as $attribute) {
                if (isset($this->_data[$attribute])) {
                    $arrRes[$attribute] = $this->_data[$attribute];
                } else {
                    $arrRes[$attribute] = null;
                }
            }

            return $arrRes;
        }

        /**
         * Converts object attributes to XML
         *
         * @param       array       $arrAttributes : array of required attributes
         * @param       string      $rootName : name of the root element
         * @return      string
         */
        public function toXml(array $arrAttributes = array(), $rootName = 'item', $addOpenTag = false, $addCdata = true)
        {
            $xml = '';

            if ($addOpenTag) {
                $xml.= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
            }

            $xml.= '<'. $rootName .'>'."\n";
            $arrData = $this->toArray($arrAttributes);

            foreach ($arrData as $fieldName => $fieldValue) {
                if ($addCdata === true) {
                    $fieldValue = "<![CDATA[". $fieldValue ."]]>";
                } else {
                    $fieldValue = str_replace(
                                              array('&', '"', "'", '<', '>'),
                                              array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'),
                                              (string)$fieldValue
                                            );
                }

                $xml.= "<". $fieldName .">". $fieldValue ."</". $fieldName .">"."\n";
            }

            $xml.= '</'. $rootName .'>'."\n";

            return $xml;
        }

        /**
         * Converts object attributes to JSON
         *
         * @param       array       $arrAttributes : array of required attributes
         * @return      string
         */
        public function toJson(array $arrAttributes = array())
        {
            $arrData = $this->toArray($arrAttributes);
            $json = Zend_Json::encode($arrData);

            return $json;
        }

        /**
         * Converts object attributes to string
         *
         * @param       array       $arrAttributes : array of required attributes
         * @param       string      $valueSeparator : separator character
         * @return      string
         */
        public function toString(array $arrAttributes = array(), $valueSeparator = ',')
        {
            $arrData = $this->toArray($arrAttributes);
            return implode($valueSeparator, $arrData);
        }

        /**
         * Checks whether the object is empty
         *
         * @return      boolean
         */
        public function isEmpty()
        {
            if (empty($this->_data)) {
                return true;
            }

            return false;
        }

        /**
         * Serialize object attributes
         *
         * @param       array       $attributes : array of required attributes
         * @param       string      $valueSeparator : separator character
         * @param       string      $fieldSeparator : separator character
         * @param       string      $quote : type of quote
         * @return      string
         */
        public function serialize(array $attributes = array(), $valueSeparator = '=', $fieldSeparator = ' ', $quote = '"')
        {
            $res  = '';
            $data = array();

            if (empty($attributes)) {
                $attributes = array_keys($this->_data);
            }

            foreach ($this->_data as $key => $value) {
                if (in_array($key, $attributes)) {
                    $data[] = $key . $valueSeparator . $quote . $value . $quote;
                }
            }

            $res = implode($fieldSeparator, $data);

            return $res;
        }

    ////////////////////////////////////////////////////////////////////////////
    //                              Debug methods                             //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Returns a linear version of the call stack
         *
         * @return      string
         */
        public function debug()
        {
            $call_info = array_shift(@debug_backtrace());
            $code_line = $call_info['line'];

            $call_info_file = explode('/', $call_info['file']);
            $file = array_pop($call_info_file);

            $s = '';
            if (@phpversion() >= 4.3) {
                $MAXSTRLEN = 64;

                $args = array();
                $s .= '<pre align=left>';
                $traceArr = @debug_backtrace();
                array_shift($traceArr);
                $tabs = sizeof($traceArr) - 1;

                foreach ($traceArr as $arr) {
                    for ($i = 0; $i < $tabs; $i++) $s .= ' &nbsp; ';
                    $tabs -= 1;
                    $s .= '<font face="Courier New, Courier" color="#0000FF">';
                    if (isset($arr['class'])) $s .= $arr['class'] .'.';

                    foreach ($arr['args'] as $v) {
                        if (is_null($v)) {
                            $args[] = 'null';
                        } else if (is_array($v)) {
                            $args[] = 'Array['. sizeof($v) .']';
                        } else if (is_object($v)) {
                            $args[] = 'Object:'. get_class($v);
                        } else if (is_bool($v)) {
                            $args[] = $v ? 'TRUE' : 'FALSE';
                        } else {
                            $v = (string) @$v;
                            $str = @htmlspecialchars(substr($v, 0, $MAXSTRLEN));

                            if (strlen($v) > $MAXSTRLEN) {
                                $str .= '...';
                            }

                            $args[] = $str;
                        }
                    }

                    $s .= $arr['function'] .'()';
                    $s .= sprintf("</font><font color=\"#808080\" size=\"-1\"> # line %s, file: %s</font>", $arr['line'], $arr['file']);
                    $s .= "\n";
                }

                $s .= '</pre>';

                return $s;
            }
        }
    }
